
/**
 * <p>Title:  </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) xio.name 2006</p>
 * @author Ray
 */
function JbpmFlowModelConverter() {
}

//
JbpmFlowModelConverter.convertModelToXML = function (model) {
    var doc = XMLDocument.newDomcument();

	//root
    var workflowProcessNode = doc.createElement(JbpmFlowModelConverter.NODE_ROOT);
	workflowProcessNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_PROCESS_NAME, model.getName());
	workflowProcessNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_PROCESS_XMLNS, "urn:jbpm.org:jpdl-3.1");
    doc.documentElement = workflowProcessNode;

    //SWIMLANES (= process roles)

    //PROCESS PROPERTIES
    JbpmFlowModelConverter.setProcessProperties(model, doc);
	
 
    //NODES

    var metaNodeModels = model.getMetaNodeModels();
    for (var i = 0; i < metaNodeModels.size(); i++) {
        var metaNodeModel = metaNodeModels.get(i);
        var activitieNode = JbpmFlowModelConverter.convertMetaNodeModelToXML(metaNodeModel, doc);
        workflowProcessNode.appendChild(activitieNode);
    }

    //
    return doc;
};
JbpmFlowModelConverter.setProcessProperties = function (model, doc) {
	var propertyNode = null;
	var action = model.action;

	for(p in action){
	    if(action[p] != ""){
	        propertyNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_PROCESS_EVENT);
            propertyNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_PROCESS_EVENT_TYPE, p.replace("_","-"));
		    var actionNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_ACTION);
            actionNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_ACTION_CLASS, action[p]);
            propertyNode.appendChild(actionNode);
            doc.documentElement.appendChild(propertyNode);
	    }
	}
};

JbpmFlowModelConverter.convertMetaNodeModelToXML = function (metaNodeModel, doc) {
    var activitieNode = doc.createElement(metaNodeModel.jbmptype);
    var transitionModels = metaNodeModel.getFroms();
    //
    activitieNode.setAttribute(JbpmFlowModelConverter.ATTR_ACTIVITIE_NAME, metaNodeModel.getText());
	//set decision
	if(metaNodeModel.jbmptype == MetaNodeModel.TYPE_JBPM_DECISION){
		activitieNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_DECISION_EXPRESSION, metaNodeModel.getCondition().conditionExpression);
	}
	
    //set action
	var actionNode = JbpmFlowModelConverter.convertActionPropertyToXML(metaNodeModel, doc);
    if(actionNode) activitieNode.appendChild(actionNode);
    //set exceptionhandler
	var exceptionhandlerNode = JbpmFlowModelConverter.convertExceptionhandlerPropertyToXML(metaNodeModel, doc);
    if(exceptionhandlerNode) activitieNode.appendChild(exceptionhandlerNode);
	//set task
	var taskNode = JbpmFlowModelConverter.convertTaskPropertyToXML(metaNodeModel, doc);
    if(taskNode) activitieNode.appendChild(taskNode);
    //set event
	var nodeEnterEvent = JbpmFlowModelConverter.convertNodeEnterEventPropertyToXML(metaNodeModel, doc);
	if(nodeEnterEvent) activitieNode.appendChild(nodeEnterEvent);
	var nodeLeaveEvent = JbpmFlowModelConverter.convertNodeLeaveEventPropertyToXML(metaNodeModel, doc);
	if(nodeLeaveEvent) activitieNode.appendChild(nodeLeaveEvent);
    //set transition
    for (var i = 0; i < transitionModels.size(); i++) {
        var transitionModel = transitionModels.get(i);
        var transitionNode = JbpmFlowModelConverter.convertTransitionModelToXML(transitionModel, doc);
        activitieNode.appendChild(transitionNode);
    }
     
    //
    return activitieNode;
};
JbpmFlowModelConverter.convertTransitionModelToXML = function (transitionModel, doc) {
    var transitionNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_TRANSITION);

    //
    transitionNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_TRANSITION_NAME, transitionModel.getText());
    transitionNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_TRANSITION_TO, transitionModel.getToMetaNodeModel().getText());

    //
    return transitionNode;
};
JbpmFlowModelConverter.convertActionPropertyToXML = function (metaNodeModel, doc) {
	var actionNode = null;
	if(metaNodeModel.jbmptype == MetaNodeModel.TYPE_JBPM_NODE){
		
	
		if(metaNodeModel.getAction().actionClass == "") return null;

		actionNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_ACTION);

		//
		actionNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_ACTION_CLASS, metaNodeModel.getAction().actionClass);
		var variables = metaNodeModel.getAction().variables;
		for(i=0;i<variables.length;i++){
			var variableNode = doc.createElement(variables[i][0]);
			if(variables[i][1].isList){
			    for(var j=0;j<variables[i][1].length;j++){
				    var elementNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_ELEMENT);
                    var cdataNode = doc.createCDATASection(variables[i][1][j]);
                    elementNode.appendChild(cdataNode);
					variableNode.appendChild(elementNode);
				}
			}else{
	            var cdataNode = doc.createCDATASection(variables[i][1]);
			    variableNode.appendChild(cdataNode);
			    //variableNode.text = variables[i][1];
			}
			actionNode.appendChild(variableNode);
		}

    }
    return actionNode;
};

JbpmFlowModelConverter.convertExceptionhandlerPropertyToXML = function (metaNodeModel, doc) {
	var actionNode = null;
	var exceptionhandlerNode = null;
	if(metaNodeModel.jbmptype == MetaNodeModel.TYPE_JBPM_NODE){
		
	
		if(metaNodeModel.getExceptionhandler().actionClass == "") return null;

	    exceptionhandlerNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_EXCEPTIONHANDLER);
		actionNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_ACTION);

		//
		actionNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_ACTION_CLASS, metaNodeModel.getExceptionhandler().actionClass);
		var variables = metaNodeModel.getExceptionhandler().variables;
		for(i=0;i<variables.length;i++){
			var variableNode = doc.createElement(variables[i][0]);
			variableNode.text = variables[i][1];
			actionNode.appendChild(variableNode);
		}
        exceptionhandlerNode.appendChild(actionNode);

    }
    return exceptionhandlerNode;
};

JbpmFlowModelConverter.convertTaskPropertyToXML = function (metaNodeModel, doc) {
	var taskNode = null;
	if(metaNodeModel.jbmptype == MetaNodeModel.TYPE_JBPM_TASK_NODE){
		
	
		if(metaNodeModel.getTask().taskName == "") return null;

		taskNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_TASK);

		//
		taskNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_TASK_NAME, metaNodeModel.getTask().taskName);

        //add description attribute
		taskNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_TASK_DESCRIPTION, metaNodeModel.getTask().description?metaNodeModel.getTask().description:"");

		//add due-date attribute
		if(metaNodeModel.getTask().duedate && metaNodeModel.getTask().duedate != ""){
		    taskNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_TASK_DUEDATE, metaNodeModel.getTask().duedate);
		}
        
		//add event node
		var events = metaNodeModel.getTask().event;
		var eventArray = new Array(new Array("task-create", events.create), new Array("task-assign", events.assign), new Array("task-start", events.start), new Array("task-end", events.end));
		for(i=0;i<eventArray.length;i++){
            if(eventArray[i][1] == null || eventArray[i][1] == "") continue;
			var eventNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_TASK_EVENT);
			eventNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_TASK_EVENT_TYPE, eventArray[i][0]);
			var eventHandlerNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_ACTION);
			eventHandlerNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_ACTION_CLASS, eventArray[i][1]);
			eventNode.appendChild(eventHandlerNode);
			taskNode.appendChild(eventNode);
		}
		//add assignment node
		var assignmentNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_TASK_ASSIGNMENT);
		var assignment =metaNodeModel.getTask().assignment;
		if(assignment.actorId != null && assignment.actorId != "") assignmentNode.setAttribute(JbpmFlowModelConverter.NODE_JBPM_TASK_ASSIGNMENT_ACTORID, assignment.actorId);
		if(assignment.pooledActors != null && assignment.pooledActors != "") assignmentNode.setAttribute(JbpmFlowModelConverter.NODE_JBPM_TASK_ASSIGNMENT_POOLEDACTORS, assignment.pooledActors);
        taskNode.appendChild(assignmentNode);

		//add controller node
		var controllerNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_TASK_CONTROLLER);
		var variables = metaNodeModel.getTask().controller.variables;
		
		for(i=0;i<variables.length;i++){
		   var variableNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_TASK_CONTROLLER_VARIABLE);
           
           variableNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_TASK_CONTROLLER_VARIABLE_NAME, variables[i][0]);
		   variableNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_TASK_CONTROLLER_VARIABLE_ACCESS, variables[i][4]);
		   controllerNode.appendChild(variableNode);
		}
        taskNode.appendChild(controllerNode);

    }
    return taskNode;
};
//
JbpmFlowModelConverter.convertNodeEnterEventPropertyToXML = function(metaNodeModel, doc){
	var eventNode = null;
	if(metaNodeModel.jbmptype == MetaNodeModel.TYPE_JBPM_TASK_NODE){
		var events = metaNodeModel.getTask().event;
		var eventArray = new Array("node-enter", new Array(events.actionname_enter, events.actionclass_enter, events.mapping_enter));
		eventNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_TASK_EVENT);
		eventNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_TASK_EVENT_TYPE, eventArray[0]);
		var action = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_ACTION);
		action.setAttribute(JbpmFlowModelConverter.NODE_JBPM_ACTION_NAME, (eventArray[1])[0]);
		action.setAttribute(JbpmFlowModelConverter.NODE_JBPM_ACTION_CLASS, (eventArray[1])[1]);
		var mapping = doc.createElement(JbpmFlowModelConverter.ACTION_JBPM_MAPPING);
		mapping.text = (eventArray[1])[2];
		action.appendChild(mapping);
		eventNode.appendChild(action);
	}
	return eventNode;
	
}
//
JbpmFlowModelConverter.convertNodeLeaveEventPropertyToXML = function(metaNodeModel, doc){
	var eventNode = null;
	if(metaNodeModel.jbmptype == MetaNodeModel.TYPE_JBPM_TASK_NODE){
		var events = metaNodeModel.getTask().event;
		var eventArray = new Array("node-leave", new Array(events.actionname_leave, events.actionclass_leave, events.mapping_leave));
		eventNode = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_TASK_EVENT);
		eventNode.setAttribute(JbpmFlowModelConverter.ATTR_JBPM_TASK_EVENT_TYPE, eventArray[0]);
		var action = doc.createElement(JbpmFlowModelConverter.NODE_JBPM_ACTION);
		action.setAttribute(JbpmFlowModelConverter.NODE_JBPM_ACTION_NAME, (eventArray[1])[0]);
		action.setAttribute(JbpmFlowModelConverter.NODE_JBPM_ACTION_CLASS, (eventArray[1])[1]);
		var mapping = doc.createElement(JbpmFlowModelConverter.ACTION_JBPM_MAPPING);
		mapping.text = (eventArray[1])[2];
		action.appendChild(mapping);
		eventNode.appendChild(action);
	}
	return eventNode;
	
}
//
JbpmFlowModelConverter.convertXMLToModel = function (doc, initModel) {
    if (!doc) {
        return null;
    }
    var model = initModel;
    if (!model) {
        model = new XiorkFlowModel();
    }

    //
    var activitieNodes = doc.getElementsByTagName("Activity");
    if(activitieNodes.length == 0){
        activitieNodes = doc.getElementsByTagName("Activitie");
    }    
    for (var i = 0; i < activitieNodes.length; i++) {
        var activitieNode = activitieNodes[i];
        var metaNodeModel = JbpmFlowModelConverter.convertXMLToMetaNodeModel(activitieNode);
        model.addMetaNodeModel(metaNodeModel);
    }

    //
    var transitionNodes = doc.getElementsByTagName("Transition");
    for (var i = 0; i < transitionNodes.length; i++) {
        var transitionNode = transitionNodes[i];
        var transitionModel = JbpmFlowModelConverter.convertXMLToTransitionModel(transitionNode, model);
        model.addTransitionModel(transitionModel);
    }

    //
    return model;
};

JbpmFlowModelConverter.convertXMLToMetaNodeModel = function (node) {
    var metaNodeModel = null;
	//
    var type = node.getAttribute(JbpmFlowModelConverter.ATTR_ACTIVITIE_TYPE);
    switch (type) {
      case MetaNodeModel.TYPE_NODE:
        metaNodeModel = new NodeModel();
        break;
      case MetaNodeModel.TYPE_START_NODE:
        metaNodeModel = new StartNodeModel();
        break;
      case MetaNodeModel.TYPE_END_NODE:
        metaNodeModel = new EndNodeModel();
        break;
      case MetaNodeModel.TYPE_FORK_NODE:
        metaNodeModel = new ForkNodeModel();
        break;
      case MetaNodeModel.TYPE_JOIN_NODE:
        metaNodeModel = new JoinNodeModel();
        break;
	  case MetaNodeModel.TYPE_DECISION_NODE:
        metaNodeModel = new DecisionNodeModel();
        break;
    }
    if (!metaNodeModel) {
        return null;
    }

    //
    var id = eval(node.getAttribute(JbpmFlowModelConverter.ATTR_ACTIVITIE_ID));
    metaNodeModel.setID(id);
    
    //
    var name = node.getAttribute(JbpmFlowModelConverter.ATTR_ACTIVITIE_NAME);
    metaNodeModel.setText(name);

    //
    var xCoordinate = eval(node.getAttribute(JbpmFlowModelConverter.ATTR_ACTIVITIE_X_COORD));
    var yCoordinate = eval(node.getAttribute(JbpmFlowModelConverter.ATTR_ACTIVITIE_Y_COORD));
    metaNodeModel.setPosition(new Point(xCoordinate, yCoordinate));

    //
    var width = eval(node.getAttribute(JbpmFlowModelConverter.ATTR_ACTIVITIE_WIDTH));
    var height = eval(node.getAttribute(JbpmFlowModelConverter.ATTR_ACTIVITIE_HEIGHT));
    metaNodeModel.setSize(new Dimension(width, height));

    //
    return metaNodeModel;
};


JbpmFlowModelConverter.convertXMLToTransitionModel = function (node, model) {
    var fromID = node.getAttribute(JbpmFlowModelConverter.ATTR_TRANSITION_FROM);
    fromMetaNodeModel = JbpmFlowModelConverter.getMetaNodeModel(model, fromID);
    var toID = node.getAttribute(JbpmFlowModelConverter.ATTR_TRANSITION_TO);
    toMetaNodeModel = JbpmFlowModelConverter.getMetaNodeModel(model, toID);

    //
    var id = eval(node.getAttribute(JbpmFlowModelConverter.ATTR_TRANSITION_ID));

    //
    var name = node.getAttribute(JbpmFlowModelConverter.ATTR_TRANSITION_NAME);
    name = name ? name : "";

    //
    var transitionModel = new TransitionModel(fromMetaNodeModel, toMetaNodeModel, id);

	//
    transitionModel.setText(name);

    //
    return transitionModel;
};

JbpmFlowModelConverter.getMetaNodeModel = function (model, id) {
    var metaNodeModels = model.getMetaNodeModels();
    for (var i = 0; i < metaNodeModels.size(); i++) {
        var metaNodeModel = metaNodeModels.get(i);
        if (metaNodeModel.getID() == id) {
            return metaNodeModel;
        }
    }
};

//static
JbpmFlowModelConverter.NODE_ROOT = "process-definition";

//
JbpmFlowModelConverter.NODE_ACTIVITIE = "Activity";
JbpmFlowModelConverter.ATTR_ACTIVITIE_ID = "id";
JbpmFlowModelConverter.ATTR_ACTIVITIE_TYPE = "type";
JbpmFlowModelConverter.ATTR_ACTIVITIE_NAME = "name";
JbpmFlowModelConverter.ATTR_ACTIVITIE_X_COORD = "xCoordinate";
JbpmFlowModelConverter.ATTR_ACTIVITIE_Y_COORD = "yCoordinate";
JbpmFlowModelConverter.ATTR_ACTIVITIE_WIDTH = "width";
JbpmFlowModelConverter.ATTR_ACTIVITIE_HEIGHT = "height";

//
JbpmFlowModelConverter.NODE_TRANSITIONS = "Transitions";
JbpmFlowModelConverter.NODE_TRANSITION = "Transition";
JbpmFlowModelConverter.ATTR_TRANSITION_ID = "id";
JbpmFlowModelConverter.ATTR_TRANSITION_NAME = "name";
JbpmFlowModelConverter.ATTR_TRANSITION_FROM = "from";
JbpmFlowModelConverter.ATTR_TRANSITION_TO = "to";

//Jbpm process-definition attribute
JbpmFlowModelConverter.ATTR_JBPM_PROCESS_NAME = "name";
JbpmFlowModelConverter.ATTR_JBPM_PROCESS_XMLNS = "xmlns";

JbpmFlowModelConverter.NODE_JBPM_TRANSITION = "transition";
JbpmFlowModelConverter.ATTR_JBPM_TRANSITION_NAME = "name";
JbpmFlowModelConverter.ATTR_JBPM_TRANSITION_TO = "to";

JbpmFlowModelConverter.NODE_JBPM_ACTION = "action";
JbpmFlowModelConverter.NODE_JBPM_ACTION_NAME = "name";
JbpmFlowModelConverter.NODE_JBPM_ACTION_CLASS = "class";
JbpmFlowModelConverter.ATTR_JBPM_ACTION_CLASS = "class";
JbpmFlowModelConverter.ACTION_JBPM_MAPPING = "mapping";
JbpmFlowModelConverter.NODE_JBPM_EXCEPTIONHANDLER = "exception-handler";

JbpmFlowModelConverter.NODE_JBPM_ELEMENT = "element";

JbpmFlowModelConverter.NODE_JBPM_TASK = "task";
JbpmFlowModelConverter.ATTR_JBPM_TASK_NAME = "name";
JbpmFlowModelConverter.ATTR_JBPM_TASK_DESCRIPTION = "description";
JbpmFlowModelConverter.ATTR_JBPM_TASK_DUEDATE = "duedate";
JbpmFlowModelConverter.NODE_JBPM_TASK_ASSIGNMENT = "assignment";
JbpmFlowModelConverter.NODE_JBPM_TASK_ASSIGNMENT_ACTORID = "actor-id";
JbpmFlowModelConverter.NODE_JBPM_TASK_ASSIGNMENT_POOLEDACTORS = "pooled-actors";
JbpmFlowModelConverter.NODE_JBPM_TASK_CONTROLLER = "controller";
JbpmFlowModelConverter.NODE_JBPM_TASK_CONTROLLER_VARIABLE = "variable";
JbpmFlowModelConverter.ATTR_JBPM_TASK_CONTROLLER_VARIABLE_NAME = "name";
JbpmFlowModelConverter.ATTR_JBPM_TASK_CONTROLLER_VARIABLE_ACCESS = "access";
JbpmFlowModelConverter.NODE_JBPM_TASK_EVENT = "event";
JbpmFlowModelConverter.ATTR_JBPM_TASK_EVENT_TYPE = "type";

JbpmFlowModelConverter.NODE_JBPM_PROCESS_EVENT = "event";
JbpmFlowModelConverter.ATTR_JBPM_PROCESS_EVENT_TYPE = "type";


JbpmFlowModelConverter.ATTR_JBPM_DECISION_EXPRESSION = "expression";